package com.ktgj.pay.phoneSound;

import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Method;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import com.ktgj.pay.utils.Toolkit;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public final class ApiV2Util {

	public static SimpleXml toSimpleXml(String xml, SimpleXml object) {
		if(object == null){
			return null;
		}
		try{
			Document doc = toDocument(xml);
			Class[] cs = new Class[]{String.class};
			for (Method m : object.getClass().getMethods()) {
				try {
					if(m.getName().startsWith("set") && m.toString().contains(object.getClass().getPackage().toString().replace("package ", ""))){
						String suffixName = m.getName().replace("set", "");
						m.invoke(object, new Object[]{ApiV2Util.getElementValue(suffixName, doc)});
					}
                } catch (Exception e) {
                    Toolkit.writeLog(xml.getClass().getName(), e.getMessage());
                }
			}
		}catch (Exception e) {
			Toolkit.writeLog(xml.getClass().getName(), e.getMessage());
		}
		return object;
	}
	
	public static SimpleXml toSimpleXml(String xml) {
		SimpleXml object = new BaseXml();
		try{
			Document doc = toDocument(xml);
			if("2.1.1".equals(getElementValue("Version", doc))){
				object = new C2CXmlImpl();
			}else if("2.1.2".equals(getElementValue("Version", doc))){
				object = new CurrencyXmlImpl();
			}else if("2.1.4".equals(getElementValue("Version", doc))){
				object = new WebCatXmlImpl(doc);
			}else if("2.3.0".equals(getElementValue("Version", doc))){
				object = new RescueXmlImpl();
			}else if("2.0.0".equals(getElementValue("Version", doc))){
				object = new MobileXmlImpl();
			}else{
				object = new SimpleXmlImpl();
			}
			return toSimpleXml(xml, object);
		}catch (Exception e) {
			Toolkit.writeLog(xml.getClass().getName(), e.getMessage());
		}
		return object;
	}
	public static Document toDocument(String xml) throws SAXException, IOException, ParserConfigurationException {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		Document doc = db.parse(new InputSource(new StringReader(xml)));
		return doc;
	}
	
	private static Object getElementValue(String elemName, Document doc) {
		String elemValue = "";
        if (null != doc) {
            Element elem = null;
            elem = (Element) doc.getElementsByTagName(elemName).item(0);
            if (null != elem && null != elem.getFirstChild()) {
                elemValue = elem.getFirstChild().getNodeValue();
            }
        }
        return elemValue;
	}
	
	public static String getNodeValue(String elemName, Element node) {
		String elemValue = "";
        if (null != node) {
            Element elem = null;
            elem = (Element) node.getElementsByTagName(elemName).item(0);
            if (null != elem && null != elem.getFirstChild()) {
                elemValue = elem.getFirstChild().getNodeValue();
            }
        }
        return elemValue;
	}
	
	/**
	 * ProcCode AccountNo ProcessCode Amount TransDatetime AcqSsn OrderNo TransData Reference RespCode TerminalNo MerchantNo MerchantOrderNo OrderState
	 * @param xml
	 * @return
	 */
	public static String getMACString(SimpleXml xml) {
		BaseXml msg = (BaseXml)xml;
		String str = msg.getProcCode()
				+ getString(msg.getAccountNo())
				+ getString(msg.getProcessCode())
				+ getString(msg.getAmount())
				+ getString(msg.getTransDatetime())
				+ getString(msg.getAcqSsn())
				+ getString(msg.getOrderNo())
				+ getString(msg.getTransData())
				+ getString(msg.getReference())
				+ getString(msg.getRespCode())
				+ getString(msg.getTerminalNo())
				+ getString(msg.getMerchantNo())
				+ getString(msg.getMerchantOrderNo())
				+ getString(msg.getOrderState());
		return str;
	}
	
	public static String getString(String src) {
		return (isNullOrEmpty(src) ? "" : (" " + src.trim())).toUpperCase();
	}
	public static boolean isNullOrEmpty(Object o) {
		return o == null || "".equals(o.toString().trim());
	}
}
